﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

namespace ConsoleUtility
{
    /// <summary>
    /// Console工具类
    /// </summary>
    public static class ConsoleHelper
    {
        private static string inputFlag = ">> "; //输入标志

        /// <summary>
        /// 输入标志
        /// </summary>
        public static string InputFlag
        {
            get { return inputFlag; }
            set { inputFlag = value ?? string.Empty; }
        }

        /// <summary>
        /// 询问用户是或否
        /// </summary>
        /// <param name="message">询问信息</param>
        /// <param name="yes">是</param>
        /// <param name="no">否</param>
        /// <param name="defaultAnswer">空值时默认结果</param>
        /// <param name="comparisonType">比较选项</param>
        /// <returns></returns>
        public static bool Ask(string message, string yes = "y", string no = "n", bool? defaultAnswer = null,
            StringComparison comparisonType = StringComparison.CurrentCultureIgnoreCase)
        {
            return Ask(message, new[] { yes }, new[] { no }, defaultAnswer, comparisonType);
        }

        /// <summary>
        /// 询问用户是或否
        /// </summary>
        /// <param name="message">询问信息</param>
        /// <param name="yes">是</param>
        /// <param name="no">否</param>
        /// <param name="defaultAnswer">空值时默认结果</param>
        /// <param name="comparisonType">比较选项</param>
        /// <returns></returns>
        public static bool Ask(string message, string[] yes, string[] no, bool? defaultAnswer = null,
            StringComparison comparisonType = StringComparison.CurrentCultureIgnoreCase)
        {
            if (yes == null || yes.Length == 0 || no == null || no.Length == 0)
            { throw new ArgumentNullException(); }

            Console.Write(message);

            if (defaultAnswer.HasValue)
            {
                if (defaultAnswer.Value)
                {
                    Console.WriteLine(" [" + yes[0] + "]/" + no[0]);
                }
                else { Console.WriteLine(" " + yes[0] + "/[" + no[0] + "]"); }
            }
            else { Console.WriteLine(" " + yes[0] + "/" + no[0]); }

            while (true)
            {
                Console.Write(inputFlag);
                var input = Console.ReadLine();

                if (defaultAnswer.HasValue && string.IsNullOrEmpty(input))
                {
                    return defaultAnswer.Value;
                }
                else if (yes.Any(y => input.Equals(y, comparisonType)))
                {
                    return true;
                }
                else if (no.Any(n => input.Equals(n, comparisonType)))
                {
                    return false;
                }
                else { Console.WriteLine("Invalid input."); }
            }
        }

        /// <summary>
        /// 读取用户输入
        /// </summary>
        /// <param name="message">信息</param>
        /// <returns></returns>
        public static string ReadLine(string message)
        {
            Console.WriteLine(message);
            Console.Write(inputFlag);

            return Console.ReadLine();
        }

        /// <summary>
        /// 询问用户选择
        /// </summary>
        /// <param name="message">询问信息</param>
        /// <param name="source">源，根据Key选择返回值</param>
        /// <returns></returns>
        public static KeyValuePair<string, string> Select(string message, Dictionary<string, string> source)
        {
            Console.WriteLine(message);

            foreach (var item in source)
            {
                Console.WriteLine(item.Key + " : " + item.Value);
            }

            Console.Write(inputFlag);
            var input = Console.ReadLine();

            string value = null;
            while (input == null || !source.TryGetValue(input, out value))
            {
                Console.WriteLine("Invalid input.");
                Console.Write(inputFlag);

                input = Console.ReadLine();
            }

            return new KeyValuePair<string, string>(input, value);
        }

        /// <summary>
        /// 设置新输出流
        /// </summary>
        /// <param name="stream">输出流</param>
        /// <returns></returns>
        public static void NewOut(Stream stream)
        {
            if (stream == null)
            {
                throw new ArgumentNullException();
            }

            Console.Out?.Close();

            var sw = new StreamWriter(stream)
            {
                AutoFlush = true
            };

            Console.SetOut(sw);
        }

        /// <summary>
        /// 设置控制台输出
        /// </summary>
        public static void StandardOut()
        {
            Console.Out?.Close();

            var sw = new StreamWriter(Console.OpenStandardOutput())
            {
                AutoFlush = true
            };

            Console.SetOut(sw);
        }
    }
}
